<?php
namespace app\data_magic\widget;

use app\data_magic\data\Field;
use app\data_magic\struct\FormField;
use app\data_magic\struct\File;
use app\data_magic\struct\Location;
use think\Db;


/**
 * 用来创建表单部件时需要的数据
 * @property array $fields 字段列表
 * @property array $data_item 数据列表
 */
class FormWidget extends Widget
{
    /**
     * @var array $hidden 表单隐藏字段
     * @var array $bind_action 绑定的操作
     */
    public $hidden=[];
    public $bind_action=[];

    /**
     * @todo 其他的操作，比如返回列表，返回搜索页，对当前的单项数据进行操作
     */

    /**
     * @var array $_fields 原始的字段列表
     * @var array $_data_item 原始的数据列表
     * @var array $__fields 字段编辑器参数列表
     */
    protected $_fields=[];
    protected $_data_item=[];
    protected $__fields=[];
    public function __set($name, $value)
    {
        if($name==="fields"){
            $this->_fields=$value;
            $this->__fields=[];
        }
        elseif($name==="data_item"){
            $this->_data_item=$value;
            $this->__fields=[];
        }
    }
    public function __get($name)
    {
        if($name==="fields"){
            if(!$this->__fields){
                $this->__fields=$this->parseEditorParams($this->_fields,$this->_data_item);
            }
            return $this->__fields;
        }
        elseif($name==="data_item"){
            return $this->_data_item;
        }
    }
    /**
     * 设置关联的操作，并且将其分类
     * @param array $actions 操作列表
     */
    public function setActions($actions)
    {

    }

    public function toArray()
    {
        $fields=[];
        foreach($this->fields as $field){
            $fields[]=$field->toArray();
        }
        return [
            "fields"=>$fields,
            "data_item"=>$this->data_item,
            "hidden"=>$this->hidden,
            "bind_action"=>$this->bind_action,
        ];
    }

    /**
     * 设置字段编辑器
     * @param Field[] $fields 字段设置
     * @param array $list 数据列表
     * @return array
     */
    public function parseEditorParams($fields,$item=[])
    {
        $fields=Field::parserFieldParams($fields);
        $item=Field::convertFromStorageFormat($fields,$item);
        $result=[];
        foreach($fields as $field){
            $struct=FormField::create($field);
            $field_name=$field->name;
            if(in_array($field->type,["select","radio","checkbox"])){
                if(isset($item[$field_name])){
                    $value = $item[$field_name];
                    $options=[];
                    /** @var Option $option */
                    foreach($field->options as $option){
                        $options[]=[
                            "name"=>$option->name,
                            "title"=>$option->title,
                            "selected"=>in_array($option->name,$value)
                        ];
                    }
                    $struct->options=$options;
                }
            }
            elseif(in_array($field->type,["datetime","date"])){
                $struct->time = isset($item[$field_name]) ? $item[$field_name] : time();
            }
            elseif($field->type==="time"){
                if(isset($item[$field_name])){
                    $struct->time = $item[$field_name] ;
                }
                else{
                    //获取今天零时到现在的秒数
                    $format_time=date("Y-m-d",0) .' '. date("H:i:s",time());
                    $struct->time=date_create_from_format("Y-m-d H:i:s",$format_time)->getTimestamp();
                }
            }
            elseif(in_array($field->type,["images","files"])){
                if(isset($item[$field_name])){
                    /** @var File $file */
                    $files=[];
                    foreach($item[$field_name] as $file){
                        $files[]=[
                            "name"=>$file->name,
                            "url"=>$file->url,
                        ];
                    }
                    $struct->uploaded=$files;
                }
            }
            elseif($field->type==="location"){
                if(isset($item[$field_name])){
                    /** @var Location $location */
                    $location=$item[$field_name];
                    $struct->location=[
                        "text"=>$location->text,
                        "longitude"=>$location->longitude,
                        "latitude"=>$location->latitude,
                    ];
                }
            }
            elseif(in_array($field->type,["refer"])){
                if(isset($item[$field_name]) && $item[$field_name]){
                    $params=$field->refer;
                    $refer_ids=implode(",",$item[$field_name]);
                    $refer=Db::table($params->table_name)
                        ->field($params->id_field.",".$params->name_field)
                        ->where($params->id_field." in ($refer_ids)")->select();
                    $id_list=[];
                    $name_list=[];
                    foreach($refer as $refer_item){
                        $id_list[]=$refer_item[$params->id_field];
                        $name_list[]=$refer_item[$params->name_field];
                    }
                    $struct->referred=[
                        "ids"=>$id_list,
                        "names"=>$name_list
                    ];
                }
            }
            elseif($field->type==="color"){
                $struct->value = isset($item[$field_name]) ? $item[$field_name] : "#000000";
            }
            else{
                if(isset($item[$field_name])){
                    $struct->value = $item[$field_name] ;
                }
            }

            $result[$field_name]=$struct;
        }
        return $result;
    }
    
    /**
     * 将字段编辑Widget输入的数据转换成内部数据
     * @param Field[] $fields 字段设置
     */
    public function convertInputData($fields,$item)
    {
        foreach($fields as $field){
            $field_name=$field->name;
            if(!$field->writable){
                continue;
            }
            elseif(in_array($field->type,["select","radio","checkbox","refer"])){
                if(isset($item[$field_name]) && is_string($item[$field_name])){
                    $item[$field_name]=explode(",",$item[$field_name]);
                }
            }
            elseif(in_array($field->type,["datetime","date","time"])){
                if(isset($item[$field_name])){
                    $format_map=["datetime"=>"Y-m-d H:i","date"=>"Y-m-d","time"=>"H:i:s"];
                    $item[$field_name]=date_create_from_format($format_map[$field->type],$item[$field_name])->getTimestamp();
                }
            }
            elseif(in_array($field->type,["images","files"])){
                if(isset($item[$field_name."_urls"]) && isset($item[$field_name."_names"])){
                    $urls = $item[$field_name."_urls"];
                    $names = $item[$field_name."_names"];
                    $file_list=[];
                    foreach($urls as $index=>$url){
                        $file=new File();
                        $file->name=isset($names[$index]) ? $names[$index] : "";
                        $file->url=$url;
                        $file_list[] = $file;
                    }
                    $item[$field_name]=$file_list;
                }
            }
            elseif($field->type==="location"){
                if(isset($item[$field_name])){
                    $location=new Location();
                    $location_params=explode(",",$item[$field_name]);
                    if(count($location_params)===2){
                        $location->longitude=$location_params[0];//经度
                        $location->latitude=$location_params[1];//纬度
                    }
                    if(isset($item[$field_name."_text"])){
                        $location->text=$item[$field_name."_text"];
                    }
                    $item[$field_name]=$location;
                }
            }
            elseif($field->type==="html"){
                if(isset($item[$field_name])){
                    $html=htmlspecialchars_decode($item[$field_name]);//将转码过的HTML代码恢复
                    $html=cmf_replace_content_file_url($html, true);//替换内容中的文件链接
                    $item[$field_name]=htmlspecialchars($html);//将HTML代码重新转码
                }
            }
        }
        return $item;
    }
}
